/*
 * CanvasSudoku.java
 *
 * Criado em 2 de Junho de 2007, 15:18
 */

package dharsudoku.gui.sudoku;

import dharsudoku.core.grafo.GrafoSudoku;
import dharsudoku.core.vertice.VerticeCoord;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * Objeto Canvas que mostra um tabuleiro sudoku, e permite edição através de eventos
 * do mouse e teclado.
 * @author Rodrigo
 */
public class CanvasSudoku extends java.awt.Canvas implements MouseListener, KeyListener {
    
    private static final int TAMANHO = 35;
    private GrafoSudoku grafo;
    private VerticeCoord selecionado;
    private boolean negrito[];
    
    /**
     * Cria uma nova instância de CanvasSudoku
     */
    public CanvasSudoku() {
	grafo = new GrafoSudoku();
	negrito = new boolean[9*9];
	
	for (int c = 0; c < 9*9; c++)
	    negrito[c] = false;
    }
    
    /**
     * Sobrescreve método paint de java.awt.Canvas
     *@param g Contexto gráfico
     */
    public void paint(Graphics g) {
	
	/* Desenha grade */
	g.setColor(java.awt.Color.GRAY);
	for (int c = 1; c <= 9; c++) {
	    g.drawLine(c*TAMANHO,TAMANHO,c*TAMANHO,TAMANHO*10);
	    g.drawLine(TAMANHO,TAMANHO*c,10*TAMANHO,TAMANHO*c);
	}
	
	g.setColor(java.awt.Color.BLACK);
	g.drawRect(TAMANHO, TAMANHO, TAMANHO*9, TAMANHO*9);
	
	g.drawLine(TAMANHO*4, TAMANHO, TAMANHO*4, TAMANHO*10);
	g.drawLine(TAMANHO*7, TAMANHO, TAMANHO*7, TAMANHO*10);
	g.drawLine(TAMANHO, TAMANHO*4, TAMANHO*10, TAMANHO*4);
	g.drawLine(TAMANHO, TAMANHO*7, TAMANHO*10, TAMANHO*7);			
	
	/* Itera grafo */
	for (java.util.Iterator i = getGrafo().getVertices().iterator(); i.hasNext(); ) {
	    VerticeCoord v = (VerticeCoord)i.next();	    
	    
	    g.setColor((negrito[((v.getX()-1)*9)+(v.getY()-1)])? java.awt.Color.BLUE : java.awt.Color.BLACK);
	    
	    /* Imprime texto */
	    if (v.getId() >= 1 && v.getId() <= 9)
		g.drawString(Integer.toString(v.getId()), v.getX()*TAMANHO + (TAMANHO/2), v.getY()*TAMANHO + (TAMANHO/2));
	}
	
	if (selecionado != null) {
	    g.setColor(java.awt.Color.BLUE);
	    g.drawRect(selecionado.getX()*TAMANHO, selecionado.getY()*TAMANHO, TAMANHO, TAMANHO);
	}
    }
    
    /**
     * Zera tabela sudoku: apaga todos números
     */
    public void zerar() {
	grafo.zerar();
	for (int c = 0; c < 9*9; c++)
	    negrito[c] = false;
	this.repaint();
    }
    
    private VerticeCoord getVertice(int px, int py) {
	
	px = (px / TAMANHO);
	py = (py / TAMANHO);
	
	/* Itera grafo */
	for (java.util.Iterator i = getGrafo().getVertices().iterator(); i.hasNext(); ) {
	    VerticeCoord v = (VerticeCoord)i.next();
	    
	    if (v.getX() == px && v.getY() == py)
		return v;
	}
	return null;
    }
    
    public void mouseClicked(MouseEvent e) {
	selecionado = getVertice(e.getX(), e.getY());
	this.repaint();
    }
    
    public void mousePressed(MouseEvent e) {
    }
    
    public void mouseReleased(MouseEvent e) {
    }
    
    public void mouseEntered(MouseEvent e) {
    }
    
    public void mouseExited(MouseEvent e) {
    }
    
    public void keyTyped(KeyEvent e) {
	if (selecionado != null && e.getKeyChar() >= '0' && e.getKeyChar() <= '9') {
	    
	    negrito[((selecionado.getX()-1)*9)+(selecionado.getY()-1)] = (e.getKeyChar() != '0');
	    
	    if (grafo.setValor(selecionado.getX(), selecionado.getY(), e.getKeyChar()-'0'))
		this.repaint();
	}
    }
    
    public void keyPressed(KeyEvent e) {
    }
    
    public void keyReleased(KeyEvent e) {
    }
    
    public GrafoSudoku getGrafo() {
	return grafo;
    }
    
    public boolean resolver() {
	boolean resultado = grafo.resolver();
	
	this.repaint();
	return resultado;
    }
    
}
